package postimpl

import (
	"errors"
	"fmt"
	"go-caipu/pkg/infra/log"
	"go-caipu/pkg/services/admin/model"
	"go-caipu/pkg/services/admin/post"
	"go-caipu/pkg/services/dto"
	"gorm.io/gorm"
)

type store interface {
	GetPostPage(cmd post.GetPostPageCommand) (data []model.SysPost, num int64, err error)
	Get(cmd post.GetPostCommand) (model.SysPost, error)
	Insert(post model.SysPost) error
	Update(post model.SysPost) error
	Remove(cmd post.RemovePostCommand) error
}
type sqlStore struct {
	db     *gorm.DB
	logger log.Logger
}

func ProvideStore(db *gorm.DB) sqlStore {
	return sqlStore{
		db:     db,
		logger: log.New("dept.store"),
	}
}

func (s sqlStore) GetPostPage(cmd post.GetPostPageCommand) (data []model.SysPost, num int64, err error) {
	err = s.db.Model(&model.SysPost{}).Scopes(
		dto.MakeCondition(cmd.GetNeedSearch()),
		dto.Paginate(cmd.GetPageSize(), cmd.GetPageIndex()),
	).Find(&data).Limit(-1).Offset(-1).Count(&num).Error
	if err != nil {
		return
	}
	return
}

func (s sqlStore) Get(cmd post.GetPostCommand) (model.SysPost, error) {
	var data model.SysPost
	err := s.db.Model(&data).First(&data, cmd.PostId).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return data, errors.New(fmt.Sprintf("postid=%d record Not found", cmd.PostId))
	}
	if err != nil {
		s.logger.Log(fmt.Sprintf("dept=%d db  error:%s", cmd.PostId, err.Error()))
		return data, err
	}

	return data, nil
}

func (s sqlStore) Insert(post model.SysPost) (err error) {
	tx := s.db.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	//查询当前部门名称是否存在
	var num int64
	err = tx.Model(&post).Where(" post_Code=?", post.PostCode).Count(&num).Error
	if err != nil {
		s.logger.Log(fmt.Sprintf("check post_code:%s is exists error:%s", post.PostCode, err.Error()))
		return err
	}
	if num > 0 {
		return errors.New(fmt.Sprintf("postcode:%s record exists", post.PostCode))
	}
	//插入
	err = tx.Create(&post).Error
	if err != nil {
		s.logger.Log(fmt.Sprintf("insert deptname:%s db  error:%s", post.PostCode, err.Error()))
		return err
	}
	return nil
}

func (s sqlStore) Update(post model.SysPost) (err error) {
	tx := s.db.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	err = tx.Save(&post).Error
	if err != nil {
		s.logger.Log(fmt.Sprintf("update  deptname:%s db  error:%s", post.PostName, err.Error()))
		return err
	}
	return nil
}

func (s sqlStore) Remove(cmd post.RemovePostCommand) (err error) {
	//判断部门存在员工则不能删除（此处写死表名，后续需要优化）
	var use int64
	tx := s.db.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	err = tx.Table("sys_user").Where("post_id IN ? ", cmd.Ids).Count(&use).Error
	if err != nil {
		return err
	}
	if use > 0 {
		return errors.New("post exists sysuser")
	}
	var data model.SysPost
	err = tx.Model(&model.SysPost{}).Delete(&data, cmd.Ids).Error
	if err != nil {
		return err
	}
	return
}
